﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace Model.Block
{
    public class ServiceChannelStorage
    {
        private readonly object locker = new object();

        private List<double> _stateChangingTime = new List<double>();

        /// <summary>
        /// Working time.
        /// </summary>
        public double WorkingTime { get; set; }

        /// <summary>
        /// Waiting time (down time).
        /// </summary>
        public double WaitingTime { get; set; }

        /// <summary>
        /// Life time.
        /// </summary>
        public double LifeTime { get { return WorkingTime + WaitingTime; } }

        /// <summary>
        /// Count of serviced requests.
        /// </summary>
        public long CountOfServiced { get; set; }

        /// <summary>
        /// Count of rejected requests.
        /// </summary>
        public long CountOfRejected { get; set; }

        /// <summary>
        /// Sum of requests waiting time in service channel queue.
        /// </summary>
        public double CommonRequestsWaitingTimeInQueue { get; set; }


        public ServiceChannelStorage()
        {
            WorkingTime = 0;
            WaitingTime = 0;
            CountOfServiced = 0;
            CountOfRejected = 0;
            CommonRequestsWaitingTimeInQueue = 0;
        }

        public double[] GetStateChangingTime()
        {
            lock (locker)
            {
                var count = (_stateChangingTime.Count % 2 == 1) ? _stateChangingTime.Count - 1 : _stateChangingTime.Count;
                var times = new double[count];
                _stateChangingTime.CopyTo(0, times, 0, count);

                _stateChangingTime = count < _stateChangingTime.Count 
                    ? new List<double>(256) {_stateChangingTime[_stateChangingTime.Count - 1]} 
                    : new List<double>(256);

                return times;
            }
        }

        private void ClearStateChangingTime()
        {
            _stateChangingTime.Clear();
            _stateChangingTime.Capacity = 256;
        }

        public void AddStateChangingTime(double time)
        {
            lock (locker)
            {
                _stateChangingTime.Add(time);
            }
        }
    }
}